package com.example.common.update;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.widget.Toast;

import com.example.common.BuildConfig;
import com.example.common.R;
import com.example.common.utils.LocalDataRecordUtils;

import java.io.File;
import java.util.Date;
import java.util.List;

import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

public class AppDialogDownloadView implements FileDownload.View, EasyPermissions.PermissionCallbacks {

    private UpdateInfo mUpdateInfo;
    private final Activity mActivity;
    private ProgressDialog mProgressDialog;
    private final LocalDataRecordUtils mLocalDataRecordUtils;

    public static void show(Activity activity, UpdateInfo updateInfo, boolean isUpdateNow) {
        new AppDialogDownloadView(activity).start(updateInfo, isUpdateNow);
    }

    public static void show(Activity activity, UpdateInfo updateInfo) {
        new AppDialogDownloadView(activity).start(updateInfo,
                isDisplayUpdateHint(activity, updateInfo.newVersion));
    }

    public static boolean isDisplayUpdateHint(Activity activity, String version) {
        String versionName = LocalDataRecordUtils.getVersionName(activity);
        if (!TextUtils.isEmpty(versionName) && !TextUtils.isEmpty(version)) {
            int newVersion = Integer.parseInt(version.replace(".", ""));
            int currentVersion = Integer.parseInt(versionName.replace(".", ""));
            if (newVersion > currentVersion) {
                return true;
            }
        }

        return false;

//        return new AppDialogDownloadView(activity).isHaveNewVersion();
    }

    private AppDialogDownloadView(Activity activity) {
        this.mActivity = activity;
        mLocalDataRecordUtils = new LocalDataRecordUtils(activity);
    }

    private boolean isHaveNewVersion() {
        String versionName = LocalDataRecordUtils.getVersionName(mActivity);
        if (!TextUtils.isEmpty(mUpdateInfo.newVersion)) {
            int newVersion = Integer.parseInt(mUpdateInfo.newVersion.replace(".", ""));
            int currentVersion = Integer.parseInt(versionName.replace(".", ""));
            if (newVersion > currentVersion) {
                return true;
            }
        }

        return false;
    }

    public void start(UpdateInfo updateInfo, boolean isUpdateNow) {
        mUpdateInfo = updateInfo;
        if (isHaveNewVersion()) {
            if (isUpdateNow) {
                initDialog(updateInfo);
            } else if (mLocalDataRecordUtils.isShouldUpdate()) {
                initDialog(updateInfo);
            }
        }
    }

    private void initDialog(UpdateInfo updateInfo) {
        AlertDialog alertDialog;
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity)
                .setTitle(updateInfo.title)
                .setMessage(updateInfo.description)
                .setPositiveButton(R.string.update, (dialog, which) -> startDownload());

        if (updateInfo.isForce) {
            alertDialog = builder.create();
        } else {
            builder.setNegativeButton(R.string.not_at_the_prompt, (dialog, which) -> {
                mLocalDataRecordUtils.setRefuseUpdateVersion(updateInfo.newVersion);
                dialog.dismiss();
            });
            alertDialog = builder.create();
        }

        alertDialog.setCancelable(false);
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();
    }

    private void startDownload() {
        String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};
        if (!EasyPermissions.hasPermissions(mActivity, permissions)) {
            String rationale = mActivity.getString(R.string.please_approve_storage_permissions);
            EasyPermissions.requestPermissions(mActivity, rationale, 0, permissions);
        } else {
            download();
        }
    }

    private void download() {
        // 开始下载
        new FileDownload.Builder()
                .setUrl(mUpdateInfo.url)
                .setUpdateView(this)
                .setSubPath(getAppName() + ".apk")
                .setDirType(Environment.DIRECTORY_DOWNLOADS)
                .download(mActivity);

        // 初始化进度条工具
        mProgressDialog = new ProgressDialog(mActivity);
        mProgressDialog.setMax(FileDownload.MAX_PROGRESS);
        mProgressDialog.setCancelable(false);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setTitle(R.string.downloading);
        mProgressDialog.setCanceledOnTouchOutside(false);
    }

    @Override
    public void successful(Uri uri) {
        dismiss();
        installApk(uri);
    }

    @Override
    public void failed() {
        dismiss();
    }

    @Override
    public void progress(float progress) {
        mProgressDialog.setProgress((int) (progress + .5F));
        if (!mProgressDialog.isShowing()) {
            mActivity.runOnUiThread(() -> mProgressDialog.show());
        }
    }

    // 关闭进度条对话框
    private void dismiss() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    // 安装应用
    private void installApk(Uri uriForDownloadedFile) {
        File file = uriToFile(uriForDownloadedFile);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            // 8.0 申请安装权限
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                boolean hasInstallPermission = mActivity.getPackageManager().canRequestPackageInstalls();
                if (!hasInstallPermission) {
                    Uri packageURI = Uri.parse("package:" + mActivity.getPackageName());
                    mActivity.startActivityForResult(new Intent(Settings
                            .ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI), 0);
                }
            }

            Uri apkUri = FileProvider.getUriForFile(mActivity, "com.example.teth.fileProvider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }

        mActivity.startActivity(intent);
    }

    // Uir 转 File
    private File uriToFile(Uri uri) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String[] image = {MediaStore.Images.Media.DATA};
            Cursor cursor = mActivity.managedQuery(uri, image, null, null, null);
            int actualImageColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return new File(cursor.getString(actualImageColumnIndex));
        }

        return new File(uri.toString());
    }

    // 获取APP名称，如果错误返回当前时间
    private String getAppName() {
        try {
            PackageManager packageManager = mActivity.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(mActivity.getPackageName(), 0);
            int labelRes = packageInfo.applicationInfo.labelRes;
            return mActivity.getResources().getString(labelRes);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return new Date().toLocaleString();
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        download();
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        if (EasyPermissions.somePermissionPermanentlyDenied(mActivity, perms)) {
            new AppSettingsDialog.Builder(mActivity).setTitle(R.string.authorization_failure)
                    .setRationale(R.string.message_select_permission).build().show();
        } else {
            Toast.makeText(mActivity, R.string.authorization_failure, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mActivity.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }
}
